package com.tianyi.redis;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * @Author tianyi
 * @Description // todo
 * @Date 2022 - 10 - 30
 **/
@Component
public class RepeatUrlDataInterceptor extends RepeatSubmitInterceptor {


    @Autowired
    private RedisOperate redisOperate;

    private byte[] getRequestPostBody(ServletRequest request) throws IOException {
        int contentLength = request.getContentLength();
        if(contentLength < 0){
            return null;
        }
        byte buffer[] = new byte[contentLength];
        for (int len = 0; len < contentLength; ) {
            int readlen = request.getInputStream().read(buffer,len, contentLength-len);
            if(readlen == -1){
                break;
            }
            len += readlen;
        }
        return buffer;
    }
    /**
     * 验证是否重复提交
     *
     * @param request    请求
     * @param annotation 注解
     * @return 是否有重得
     */
    @Override
    public boolean isRepeatSubmit( HttpServletRequest request, RepeatAnnotation annotation) {
        String params = "";
        //  从请求中的body中取参数
        try {
            params = getPostBodyParams(request.getInputStream(),request.getCharacterEncoding());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 如果body参数为空，则从paramter中取
        if (StringUtils.isEmptyOrWhitespaceOnly(params)) {
            try {
                params = new ObjectMapper().writeValueAsString(request.getParameterMap());
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        // 请求的地址
        String url = request.getRequestURI();
        // 唯一的值
        String[] uniqueKeys = annotation.uniqueKey();
        Map<String, Object> paramMap = JSON.parseObject(params, Map.class);
        String uniqueValues = "";
        String uniqueKeyStr = "";
        for (String key : uniqueKeys) {
            uniqueValues += paramMap.get(key) + "*";
            uniqueKeyStr += key + "*";
        }
        // 唯一的标识
        String repeatedKey = url + "*" + uniqueKeyStr;

        // 先检查redis中是否有这个值

        if (redisOperate.exists(repeatedKey) == false) {
            // 如果没有这个值，则写入进去,并返回结果为不重复
            redisOperate.setEx(repeatedKey, uniqueValues, annotation.interval());
            return false;
        }
        // 返回结果为重复
        return true;

    }

    private String getPostBodyParams(ServletInputStream inputStream, String charset) {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(charset)));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            sb.append("get body params fail");
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }
        }
        return sb.toString();
    }
}
